package org.flexthinker.module
{
    import flash.events.Event;

    import mx.events.FlexEvent;

    import mx.events.ModuleEvent;

    import mx.modules.Module;

    import org.flexthinker.module.impl.CompositeModuleDescriptorLoader;
    import org.flexthinker.module.impl.ModuleDescriptor;
    import org.flexunit.async.Async;
    import org.fluint.uiImpersonation.UIImpersonator;
    import org.hamcrest.assertThat;
    import org.hamcrest.object.equalTo;

    import spark.components.Button;

    /**
     * To test ModuleViewLoaderMXML, where the declaration for descriptor and the view loader is part of mxml.
     */
    public class ModuleViewLoaderMXMLTest
    {
        private var mxml:ModuleViewLoaderMXML;

        CompositeModuleDescriptorLoader;

        public function ModuleViewLoaderMXMLTest()
        {

        }

        [Before(async,ui,timeout="2000")]
        public function setUp():void
        {
            mxml = new ModuleViewLoaderMXML();
            Async.proceedOnEvent(this, mxml, FlexEvent.CREATION_COMPLETE, 1000);
            UIImpersonator.addChild(mxml);

//            Log.addTarget( mxml.traceTarget );
        }

        [After]
        public function tearDown():void
        {
            mxml.compositeModuleLoader.unload();
            mxml.compositeModuleAndSkinLoader.unload();
            mxml.compositeModuleLoader.unload();

            UIImpersonator.removeChild(mxml);
            mxml = null;
        }

        [Test(async,ui,timeout="6000")]
        public function testCompositeModuleDescriptorLoading():void
        {
            assertThat("module descriptor should have had 1 dependency",
                    mxml.moduleWithSkinDescriptor.dependencies.length, equalTo(1));
            assertThat("composite descriptor should have had 2 children",
                    mxml.compositeModuleDescriptor.children.length, equalTo(2));
            assertThat("composite descriptor should have had 1st children as ModuleDescriptor",
                    mxml.compositeModuleDescriptor.children[0] is ModuleDescriptor, equalTo(true));
            assertThat("loader should have had a moduleDescriptor", mxml.compositeModuleLoader.moduleDescriptor != null,
                    equalTo(true));

            Async.handleEvent(this, mxml.compositeModuleLoader, Event.COMPLETE, completeHandler, 2000);
            mxml.compositeModuleLoader.addEventListener(ModuleEvent.ERROR, errorHandler, false, 0, true);
            mxml.compositeModuleLoader.load();
        }

        private function completeHandler(event:Event, param:Object = null):void
        {
            var module1:Module = Module(mxml.compositeModuleLoader.getElementAt(0));
            var module2:Module = Module(mxml.compositeModuleLoader.getElementAt(1));

            assertThat("module's style was not loaded correctly",
                    module1.styleManager.getStyleDeclaration("spark.components.Button").getStyle("color"),
                    equalTo(0xFF0000));
            assertThat("module's style was not loaded correctly",
                    module2.styleManager.getStyleDeclaration("spark.components.Button").getStyle("color"),
                    equalTo(0x0000FF));

//           Async.handleEvent(this, mxml.loader, Event.COMPLETE, completeHandler, 5000);
        }


        private function errorHandler(event:ModuleEvent):void
        {
            trace("ERROR");
            assertThat("module should have loaded", event.errorText, equalTo("Error is:"));
        }

        [Test(async,timeout="6000")]
        public function testModuleDescriptorLoading():void
        {
            Async.handleEvent(this, mxml.moduleWithSkinLoader, Event.COMPLETE, completeHandler2, 2000);
            mxml.moduleWithSkinLoader.addEventListener(ModuleEvent.ERROR, errorHandler, false, 0, true);
            mxml.moduleWithSkinLoader.load();
        }

        private function completeHandler2(event:Event, param:Object):void
        {
            var module1:Module = Module(mxml.moduleWithSkinLoader.getElementAt(0));
            assertThat("module's style was not loaded correctly",
                    module1.styleManager.getStyleDeclaration("spark.components.Button").getStyle("color"),
                    equalTo(0xFF0000));
        }


        [Test(async,timeout="6000")]
        public function testModuleAndSkinLoading():void
        {
            Async.handleEvent(this, mxml.compositeModuleAndSkinLoader, Event.COMPLETE, completeHandler3, 2000);
            mxml.compositeModuleAndSkinLoader.addEventListener(ModuleEvent.ERROR, errorHandler, false, 0, true);
            mxml.compositeModuleAndSkinLoader.load();
        }

        private function completeHandler3(event:Event, param:Object):void
        {
            var module1:Module = Module(mxml.compositeModuleAndSkinLoader.getElementAt(1));
            assertThat("module's style was not loaded correctly",
                    module1.styleManager.getStyleDeclaration("spark.components.Button").getStyle("color"),
                    equalTo(0xFF0000));

            var btn:Button = Button(mxml.compositeModuleAndSkinLoader.getElementAt(0));
            assertThat("button with MXML doesn't have the style updated",
                    btn.styleManager.getStyleDeclaration("spark.components.Button").getStyle("color"),
                    equalTo(0x0000FF));

//            Async.handleEvent(this, mxml.compositeModuleAndSkinLoader, Event.COMPLETE, completeHandler, 5000);
        }

    }
}